﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using ShevaEngine.Core.Modules.Scenes;

namespace ShevaEngine.Core.Modules.Graphics.Cameras
{
    /// <summary>
    /// Abstract class camera.
    /// </summary>
    public class Camera : SceneObject
    {
        /// <summary>View matrix.</summary>
        private Matrix _ViewMatrix;
        /// <summary>Projection matrix.</summary>
        public Matrix ProjectionMatrix;
        /// <summary>Near plane.</summary>
        public float NearPlane;
        /// <summary>Far plane.</summary>
        public float FarPlane;
        /// <summary>Frustum.</summary>
        public BoundingFrustum Frustum { get; private set; }
        /// <summary>Up vector.</summary>
        public Vector3 UpVector;
        /// <summary>Camera position.</summary>
        public Vector3 Position { get { return Matrix.Invert(this._ViewMatrix).Translation; } }
        /// <summary>View matrix.</summary>
        public Matrix ViewMatrix
        {
            get { return this._ViewMatrix; }
            set
            {
                this._ViewMatrix = value;

                this.Frustum = new BoundingFrustum(this._ViewMatrix * this.ProjectionMatrix);
            }
        }
        /// <summary>World matrix.</summary>
        public override Matrix World { get { return this.ViewMatrix; } set { this.ViewMatrix = value; } }
        
        /// <summary>
        /// Constructor.
        /// </summary>
        public Camera()
        {
            this._ViewMatrix = Matrix.Identity;
            this.ProjectionMatrix = Matrix.Identity;
            this.NearPlane = 0.1f;
            this.FarPlane = 10000;
        }

        /// <summary>
        /// Method creates projection matrix.
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public void CreateProjectionMatrix(float aspectRatio)
        {
            this.ProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
                aspectRatio, this.NearPlane, this.FarPlane);

            this.Frustum = new BoundingFrustum(this._ViewMatrix * this.ProjectionMatrix);
        }

        /// <summary>
        /// Methods add items in rendering pipeline.
        /// </summary>
        /// <param name="renderinPipeline"></param>
        public void AddInRenderingPipeline(RenderingPipeline renderingPipeline, Camera camera) { }

        /// <summary>
        /// Methods add items in rendering pipeline.
        /// </summary>
        /// <param name="renderinPipeline"></param>
        public void AddInRenderingPipeline(RenderingPipeline renderingPipeline, Vector3 position, float distance) { }
    }
}
